#!/bin/bash

# Vue + TypeScript + ESLint 快速配置脚本 (Shell 版本)
# 一键解决模块解析、路径别名、重复报错等常见问题
#
# 使用方法：
# 1. chmod +x quick-setup-vue-ts-eslint.sh
# 2. ./quick-setup-vue-ts-eslint.sh

set -e  # 遇到错误立即退出

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}$1${NC}"
}

log_success() {
    echo -e "${GREEN}$1${NC}"
}

log_warning() {
    echo -e "${YELLOW}$1${NC}"
}

log_error() {
    echo -e "${RED}$1${NC}"
}

log_header() {
    echo -e "${MAGENTA}$1${NC}"
}

log_cyan() {
    echo -e "${CYAN}$1${NC}"
}

# 检查是否在项目根目录
check_project_root() {
    if [ ! -f "package.json" ]; then
        log_error "❌ 未找到 package.json，请确保在项目根目录运行此脚本"
        exit 1
    fi
}

# 检查必要依赖
check_dependencies() {
    log_info "📦 检查项目依赖..."
    
    local required_deps=("vue" "@vitejs/plugin-vue" "typescript" "vue-tsc" "eslint" "@typescript-eslint/parser" "@typescript-eslint/eslint-plugin" "eslint-plugin-vue")
    local missing_deps=()
    
    for dep in "${required_deps[@]}"; do
        if ! grep -q "\"$dep\"" package.json; then
            missing_deps+=("$dep")
        fi
    done
    
    if [ ${#missing_deps[@]} -ne 0 ]; then
        log_error "❌ 缺少以下必要依赖:"
        for dep in "${missing_deps[@]}"; do
            echo "   - $dep"
        done
        echo ""
        log_warning "💡 请先安装缺少的依赖："
        echo "   npm install -D ${missing_deps[*]}"
        echo "   或"
        echo "   pnpm add -D ${missing_deps[*]}"
        exit 1
    fi
    
    log_success "✅ 依赖检查通过"
}

# 备份现有配置
backup_configs() {
    log_info "💾 备份现有配置..."
    
    local timestamp=$(date +"%Y-%m-%d_%H-%M-%S")
    local backup_dir=".config-backup-$timestamp"
    local files_to_backup=("tsconfig.app.json" ".eslintrc.cjs" ".eslintrc.js" ".eslintrc.json" "src/vite-env.d.ts")
    local backed_up_files=()
    
    for file in "${files_to_backup[@]}"; do
        if [ -f "$file" ]; then
            if [ ! -d "$backup_dir" ]; then
                mkdir -p "$backup_dir"
            fi
            cp "$file" "$backup_dir/$(basename "$file")"
            backed_up_files+=("$file")
        fi
    done
    
    if [ ${#backed_up_files[@]} -ne 0 ]; then
        log_success "✅ 已备份 ${#backed_up_files[@]} 个配置文件到: $backup_dir"
        for file in "${backed_up_files[@]}"; do
            echo "   - $file"
        done
        echo "$backup_dir"  # 返回备份目录名
    else
        log_warning "⚠️ 未找到需要备份的配置文件"
        echo ""  # 返回空字符串
    fi
}

# 创建 TypeScript 配置
create_tsconfig() {
    log_info "🔧 创建 tsconfig.app.json..."
    
    cat > tsconfig.app.json << 'EOF'
{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "include": [
    "env.d.ts",
    "src/**/*",
    "src/**/*.vue"
  ],
  "exclude": [
    "src/**/__tests__/*"
  ],
  "compilerOptions": {
    "composite": true,
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}
EOF
    
    log_success "✅ 创建/更新: tsconfig.app.json"
}

# 创建 Vue 模块声明
create_vite_env() {
    log_info "🔧 创建 src/vite-env.d.ts..."
    
    mkdir -p src
    
    cat > src/vite-env.d.ts << 'EOF'
/// <reference types="vite/client" />

// 为 .vue 单文件组件提供模块声明，供 TypeScript 识别
// 说明：使用 DefineComponent 的默认泛型，避免使用 `{}` 与 `any` 以通过更严格的 ESLint 规则
declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent
  export default component
}
EOF
    
    log_success "✅ 创建/更新: src/vite-env.d.ts"
}

# 创建 ESLint 配置
create_eslintrc() {
    log_info "🔧 创建 .eslintrc.cjs..."
    
    cat > .eslintrc.cjs << 'EOF'
/*
 * ESLint 配置：与 TypeScript 规则对齐，支持 Vue 3 + <script setup> + TS
 * - 关闭 ESLint 层的未使用变量检测，交由 TypeScript 编译器（TS6133）统一处理
 * - 引入 unplugin-auto-import 生成的全局声明，避免无谓的未定义报错
 */

// 引入自动导入生成的全局变量定义
const autoImportGlobals = (() => {
  try {
    // eslint-disable-next-line @typescript-eslint/no-var-requires
    const cfg = require('./.eslintrc-auto-import.json')
    return cfg.globals || {}
  } catch (e) {
    return {}
  }
})()

module.exports = {
  root: true,
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  // 使用 Vue 的解析器，转交 <script> 内容给 TS 解析器
  parser: 'vue-eslint-parser',
  parserOptions: {
    parser: '@typescript-eslint/parser',
    ecmaVersion: 'latest',
    sourceType: 'module',
    extraFileExtensions: ['.vue'],
  },
  plugins: ['vue', '@typescript-eslint'],
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-recommended',
    'plugin:@typescript-eslint/recommended',
  ],
  rules: {
    // 与 TS 编译器保持一致：未使用变量交由 TS 处理，避免重复报错
    'no-unused-vars': 'off',
    '@typescript-eslint/no-unused-vars': 'off',

    // 常见工程化约定
    'vue/multi-word-component-names': 'off',
  },
  globals: {
    ...autoImportGlobals,
  },
  ignorePatterns: [
    'dist/',
    'node_modules/',
    'src/types/*.d.ts',
  ],
}
EOF
    
    log_success "✅ 创建/更新: .eslintrc.cjs"
}

# 验证配置
validate_config() {
    log_info "🔍 验证配置..."
    
    # 检查 TypeScript
    if grep -q '"check"\|"type-check"' package.json; then
        log_cyan "运行 TypeScript 检查..."
        if npm run check 2>/dev/null || npm run type-check 2>/dev/null; then
            log_success "✅ TypeScript 类型检查通过"
        else
            log_warning "⚠️ TypeScript 检查有警告，这是正常的，可能需要清理代码中的未使用变量"
        fi
    else
        log_warning "⚠️ 未找到 TypeScript 检查脚本，建议在 package.json 中添加:"
        echo '   "check": "vue-tsc -b"'
    fi
    
    # 检查 ESLint
    if grep -q '"lint"' package.json; then
        log_cyan "运行 ESLint 检查..."
        if npm run lint 2>/dev/null; then
            log_success "✅ ESLint 检查通过"
        else
            log_warning "⚠️ ESLint 检查有警告，可运行 \"npm run lint:fix\" 自动修复格式问题"
        fi
    else
        log_warning "⚠️ 未找到 ESLint 检查脚本，建议在 package.json 中添加:"
        echo '   "lint": "eslint . --ext .ts,.vue"'
        echo '   "lint:fix": "eslint . --ext .ts,.vue --fix"'
    fi
}

# 显示完成信息
show_completion() {
    local backup_dir="$1"
    
    echo ""
    log_success "🎉 配置完成！"
    
    if [ -n "$backup_dir" ]; then
        log_cyan "📁 原配置已备份到: $backup_dir"
    fi
    
    echo ""
    log_info "🔧 可用命令："
    echo "   npm run check     # TypeScript 类型检查"
    echo "   npm run lint      # ESLint 代码检查"
    echo "   npm run lint:fix  # ESLint 自动修复格式问题"
    echo "   npm run dev       # 启动开发服务器"
    echo "   npm run build     # 构建生产版本"
    
    echo ""
    log_info "💡 接下来的步骤："
    echo "   1. 重启你的 IDE (VS Code 等) 以加载新配置"
    echo "   2. 运行 \"npm run lint:fix\" 自动修复代码格式"
    echo "   3. 运行 \"npm run check\" 确保类型检查通过"
    echo "   4. 开始愉快地开发吧！"
    
    echo ""
    log_info "🚨 常见问题解决："
    echo "   - 如果 IDE 仍提示找不到模块，请重启 IDE"
    echo "   - 如果路径别名不工作，检查 vite.config.ts 中的 alias 配置"
    echo "   - 如果有未使用变量警告，运行 \"npm run lint:fix\" 或手动清理"
    
    if [ -n "$backup_dir" ]; then
        echo ""
        log_warning "🔄 如需回滚配置，请从 $backup_dir 目录恢复文件"
    fi
}

# 主函数
main() {
    echo ""
    log_header "🚀 Vue + TypeScript + ESLint 快速配置工具"
    log_cyan "   解决模块解析、路径别名、重复报错等常见问题"
    echo ""
    
    # 1. 检查项目根目录
    check_project_root
    
    # 2. 检查依赖
    check_dependencies
    
    # 3. 备份现有配置
    backup_dir=$(backup_configs)
    
    # 4. 应用新配置
    create_tsconfig
    create_vite_env
    create_eslintrc
    
    # 5. 验证配置
    validate_config
    
    # 6. 显示完成信息
    show_completion "$backup_dir"
}

# 执行主函数
main "$@"